#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

#ifdef _WIN32
#include <windows.h>
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#include <sys/time.h>
#endif

#include "base.h"

/// @brief 获取当前时间存储到timebuf中 长度为20
/// @param timebuf
void now_str(char *timebuf)
{
    time_t rawtime;
    struct tm *timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(timebuf, 80, "%Y-%m-%d %H:%M:%S", timeinfo);
}

/// @brief 获取当前时间戳（毫秒级）
/// @return
long long now_ms()
{
#ifdef _WIN32
    FILETIME ft;
    GetSystemTimeAsFileTime(&ft);
    unsigned long long tmpres = 0;
    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;
    tmpres /= 10; // convert into microseconds
    tmpres -= DELTA_EPOCH_IN_MICROSECS;
    return tmpres / 1000; // Convert into milliseconds
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return ((long long)tv.tv_sec * 1000LL + (long long)tv.tv_usec / 1000LL);
#endif
}

/// @brief 文件最后的更新时间
/// @param path 文件路径
/// @return 成功:time_t  失败:-1
time_t fltime(const char *path)
{
    struct stat st;
    // 数据最后的修改时间
    return stat(path, &st) ? -1 : st.st_mtime;
}

/// @brief 获取文件大小
/// @param path 文件路径
/// @return 成功:文件大小 失败:-1
size_t fsize(const char *path)
{
    struct stat st;
    // 文件大小
    return stat(path, &st) ? -1 : st.st_size;
}


int get_rand_str(char *str,const int len)
{
	int i, random_num, seed_str_len;
    unsigned int seed_num;
    char seed_str[] = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; //随机字符串的随机字符集

    seed_str_len = strlen(seed_str);
    
    seed_num = (unsigned int)(now_ms()); //超了unsigned int的范围也无所谓，我们要的只是不同的种子数字
    srand(seed_num);

    for(i = 0; i < len; i++)
    {
        random_num = rand()%seed_str_len;
        str[i] = seed_str[random_num];
    }
    return 0;
}

/// @brief 记录步骤开始时间
/// @param step step_t 变量地址
void step_start(step_t *step)
{
    step->start = now_ms();
}

/// @brief 记录步骤结束时间
/// @param step step_t 变量地址
/// @return 用时
long long step_end(step_t *step)
{
    step->end = now_ms();
    return step->end - step->start;
}